/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.apiGenerator.dataType.entityInterface.propertyInfo;

import com.inspur.edp.bef.bizentity.GspBizEntityElement;
import com.inspur.edp.caf.generator.BaseGenerator;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.item.ClassGenerator;
import com.inspur.edp.caf.generator.item.ClassGeneratorContext;
import com.inspur.edp.caf.generator.property.ClassPropertyGenerator;
import com.inspur.edp.caf.generator.property.PropertyGenerator;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.designtime.api.element.GspEnumValue;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.DotNetToJavaStringHelper;
import com.inspur.edp.cef.generator.apiGenerator.dataType.entityInterface.assoInfo.AssociationInfoGen;
import com.inspur.edp.cef.generator.apiGenerator.dataType.entityInterface.dataTypeInfo.DataTypeInfoGeneratorContext;
import com.inspur.edp.cef.generator.apiGenerator.dataType.entityInterface.enumValueInfo.EnumValueInfoGen;
import com.inspur.edp.cef.generator.apiGenerator.dataType.mgrInterface.mgrInfo.DisplayValueKeyPropGen;
import com.inspur.edp.cef.spi.entity.AbstractPropertyInfo;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;

public class DataTypePropInfoGenerator extends ClassGenerator {
  protected DataTypeInfoGeneratorContext parentContext;
  protected IGspCommonField field;

  public DataTypePropInfoGenerator(
      DataTypeInfoGeneratorContext parentContext, IGspCommonField field) {
    super(parentContext.getDataTypeInterfaceCtx().getApiGenContext().getCompilationUnitInfo());
    this.parentContext = parentContext;
    this.field = field;
  }

  @Override
  protected void beforeInitialize() {
    super.beforeInitialize();
    if (!field.getIsRefElement()) {
      // 关联带出字段，不应加到节点字段类型字典中
      // wj0416-此处getNameSpace()返回值为空，同工程写类名即可
      parentContext
          .getPropertyInfoTypeDic()
          .put(
              this.field.getLabelID(),
              new MediateType(super.compileUnit.getPackageName(), getName()));
    }
  }


  // keyword:
  // ORIGINAL LINE: protected new DataTypPropInfoGenCtx getContext() { return
  // (DataTypPropInfoGenCtx)((super.getContext() instanceof DataTypPropInfoGenCtx) ?
  // super.getContext() : null); }
  @Override
  protected DataTypPropInfoGenCtx getContext() {
    return (DataTypPropInfoGenCtx)
        ((super.getContext() instanceof DataTypPropInfoGenCtx) ? super.getContext() : null);
  }

  @Override
  protected ClassGeneratorContext createClassInfoContext() {
    return new DataTypPropInfoGenCtx(parentContext, field);
  }

  @Override
  protected java.util.ArrayList<ModifierKeyword> getAccessModifier() {
    return new java.util.ArrayList<ModifierKeyword>(
        java.util.Arrays.asList(new ModifierKeyword[] {ModifierKeyword.PUBLIC_KEYWORD}));
  }

  @Override
  protected final TypeInfo setParentClass() {
    java.lang.Class type = getParentClassType();
    if (!AbstractPropertyInfo.class.isAssignableFrom(type)) {
      throw new RuntimeException("DataTypePropInfoGenerator生成器的生成基类应为AbstractPropertyInfo及其子类。");
    }
    return new TypeInfo(type.getName());
  }

  @Override
  protected String getName() {
    if(field.getBelongObject() instanceof UnifiedDataTypeDef){
      return field.getLabelID() + "PropInfo";
    }
    return field.getBelongObject().getCode() + field.getLabelID() + "PropInfo";


  }

  @Override
  protected final java.util.ArrayList<ClassPropertyGenerator> createPropertyGenerators() {
    java.util.ArrayList<ClassPropertyGenerator> rez =
        new java.util.ArrayList<ClassPropertyGenerator>(
            java.util.Arrays.asList(
            new ClassPropertyGenerator[] {
                    new PropInfoNameGenerator(parentContext.getDataTypeInterfaceCtx(), field),
                    new PropInfoRequiredGenerator(parentContext.getDataTypeInterfaceCtx(), field),
                    new PropInfoPrecisionGenerator(parentContext.getDataTypeInterfaceCtx(), field),
                    new PropInfoLengthGenerator(parentContext.getDataTypeInterfaceCtx(), field),
                    new DisplayValueKeyPropGen(field.getI18nResourceInfoPrefix() + "." + "Name"),
                    new PropInfoTypeGenerator(parentContext.getDataTypeInterfaceCtx(), field),
                    new PropInfoFieldRtrimGenerator(parentContext.getDataTypeInterfaceCtx(), field),
            }));

    		if(!DotNetToJavaStringHelper.isNullOrEmpty(field.getDefaultValue()))
    		{
    			rez.add(new DefaultValueGenerator(field, parentContext));
    		}
    // TODO:
    if(field instanceof GspBizEntityElement){
      rez.add(new PropInfoIsDefaultNullGenerator(parentContext.getDataTypeInterfaceCtx(),(GspBizEntityElement)field));
    }
    if (field.getIsUdt()) {
      rez.add(new PropInfoIsUdtGenerator(parentContext.getDataTypeInterfaceCtx(), field));
      rez.add(new PropInfoUdtConfigIdGenerator(parentContext.getDataTypeInterfaceCtx(), field));
    }
    if (field.getHasAssociation()) {
      rez.add(new PropertyInfoAssociationGenerator(parentContext.getDataTypeInterfaceCtx(), field));
      rez.add(new PropertyInfoAssoInfoTypeGenerator(getContext()));
      rez.add(new IsAssociationGenerator(parentContext.getDataTypeInterfaceCtx(), field));
    } else if (field.getObjectType() == GspElementObjectType.Enum) {
      rez.add(new IsEnumGenerator(getContext()));
      rez.add(new PropertyInfoEnumInfoTypesDicGen(getContext()));
    }
    java.util.ArrayList<ClassPropertyGenerator> extendProps =
        createPropInfoExtendPropertyGenerators();
    if (extendProps != null) {
      rez.addAll(extendProps);
    }
    return rez;
  }

  @Override
  protected final java.util.ArrayList<BaseGenerator> createClassExtendChildGenrators() {
    java.util.ArrayList<BaseGenerator> list =
        ((super.createClassExtendChildGenrators()) != null)
            ? super.createClassExtendChildGenrators()
            : new java.util.ArrayList<BaseGenerator>();
    if (field.getHasAssociation()) {
      list.add(getAssoInfoGenerator(field.getChildAssociations().get(0)));
    }
    else if (field.getObjectType() == GspElementObjectType.Enum) {
      for (GspEnumValue enumValue : field.getContainEnumValues()) {
        list.add(new EnumValueInfoGen(getContext(), enumValue));
      }
    }
    java.util.ArrayList<PropertyGenerator> extend = createPropInfoExtendChildGenerators();
    if (extend != null && extend.size() > 0) {
      list.addAll(extend);
    }
    return list;
  }

  protected java.util.ArrayList<ClassPropertyGenerator> createPropInfoExtendPropertyGenerators() {
    return null;
  }

  protected java.util.ArrayList<PropertyGenerator> createPropInfoExtendChildGenerators() {
    return null;
  }

  protected java.lang.Class getParentClassType() {
    return AbstractPropertyInfo.class;
  }

  protected AssociationInfoGen getAssoInfoGenerator(GspAssociation asso) {
    return new AssociationInfoGen(getContext(), asso);
  }
}
